const logger = require('log4js').getLogger()
const taobaoClient = require('../mng/taobaoClientMng').client
const config = require('../util/config')
const formatDate = require('../../lib/formatDate')
const chromeMng = require('../mng/chromeMng')
const ChromeServerIterator = require('../mng/chromeServerMng').Iterator
const crypto = require('crypto')
const jd = require('../mng/jd')

function getActualLinkFromChrome(link, exclude) {
    exclude = exclude || []
    return new Promise((resolve, reject) => {
        let chromeServer = require('../mng/chromeServerMng').get(exclude)
        if (!chromeServer) {
            require('../mng/pushMng').push('no chrome servers')
            reject()
            return
        }
        var url = chromeServer + 'getActualLink.do'
        logger.debug('[' + __filename + ':' + __line + ']', 'get actual link from chrome', url, link)
        require('../util/getHtml')({
            url,
            data: JSON.stringify({
                link: link
            })
        }).then(result => {
            logger.debug('[' + __filename + ':' + __line + ']', 'get actual link from chrome', url, link, result)
            var item = JSON.parse(result)
            if (item.result != 1) {
                exclude.push(chromeServer)
                getActualLinkFromChrome(link, exclude).then(result => {
                    resolve(result)
                }, result => {
                    reject(result)
                })
            } else {
                resolve(item.actualLink)
            }
        }, result => {
            exclude.push(chromeServer)
            getActualLinkFromChrome(link, exclude).then(result => {
                resolve(result)
            }, result => {
                reject(result)
            })
        })
    })
}

function getFromJDAPI(link) {
    return new Promise((resolve, reject) => {
        jd.union.open.promotion.common.get(link).then(result => {
            let advLink = result
            var match = link.match(/https:\/\/item.jd.com\/(\d+).html/)
            if (!match) {
                match = link.match(/https:\/\/item.m.jd.com\/product\/(\d+).html/)
                if (!match) {
                    reject()
                    return
                }
            }
            jd.union.open.goods.promotiongoodsinfo.query(match[1]).then(result => {
                resolve({
                    advLink: advLink,
                    rate: Math.round(result[0].commisionRatioWl * config.returnRate * 100) / 100,
                    title: result[0].goodsName,
                    price: result[0].unitPrice
                })
            }, result => {
                if (result)
                    logger.error('[' + __filename + ':' + __line + ']', result)
                reject()
            })
        }, result => {
            if (result)
                logger.error('[' + __filename + ':' + __line + ']', result)
            reject()
        })
    })
}

function getFromCouponAPI(link) {
    return new Promise((resolve, reject) => {
        if (link.indexOf('taobao') == -1 && link.indexOf('tmall') == -1) {
            reject()
            return
        }
        var iid = require('url').parse(link, true).query.id
        taobaoClient.execute('taobao.tbk.item.info.get', {
            'num_iids': iid
        }, (err, result) => {
            if (err) {
                logger.error('[' + __filename + ':' + __line + ']', JSON.stringify(err))
                reject()
                return
            }
            if (!result.results) {
                logger.error('[' + __filename + ':' + __line + ']', result)
                reject()
                return
            }
            if (result.results.n_tbk_item.length == 0) {
                reject()
                return
            }
            taobaoClient.execute('taobao.tbk.dg.item.coupon.get', {
                adzone_id: '57204670',
                q: result.results.n_tbk_item[0].title
            }, (err, result) => {
                if (err) {
                    logger.error('[' + __filename + ':' + __line + ']', err)
                    reject()
                    return
                }
                if (!result.results) {
                    logger.error('[' + __filename + ':' + __line + ']', result)
                    reject()
                    return
                }
                var coupons = result.results.tbk_coupon
                for (var i = 0; i < coupons.length; i++) {
                    if (iid == coupons[i].num_iid && coupons[i].coupon_remain_count > 0) {
                        logger.debug('[' + __filename + ':' + __line + ']', JSON.stringify(coupons[i]))
                        var item = {
                            price: coupons[i].zk_final_price,
                            rate: Math.round(coupons[i].commission_rate * config.returnRate * 100) / 100,
                            advLink: coupons[i].coupon_click_url,
                            title: coupons[i].title
                        }
                        new Promise((resolve, reject) => {
                            getTpwd(item.advLink).then(result => {
                                item.tpwd = result
                                resolve()
                            }, result => {
                                resolve()
                            })
                        }).then(result => {
                            resolve(item)
                        })
                        return
                    }
                }
                reject()
            })
        })
    })
}

function getFromDB(link) {
    return new Promise((resolve, reject) => {
        const mongoMng = require('../mng/mongoMng')
        if (!mongoMng.db) {
            logger.error('[' + __filename + ':' + __line + ']', 'mongodb未连接')
            reject()
            return
        }
        var createTime = new Date()
        createTime.setTime(createTime.getTime() - 86400000 * 30)
        logger.debug('[' + __filename + ':' + __line + ']', {
            link: link,
            createTime: {
                $gt: createTime
            }
        })
        mongoMng.db.collection('item').find({
            link: link,
            createTime: {
                $gt: createTime
            }
        }).toArray((err, result) => {
            if (err) {
                log(err)
                reject()
                return
            }
            if (result.length == 0) {
                reject()
                return
            }
            var item = result[0]
            if (!item.advLink) {
                reject()
                return
            }
            if (item.advLink == -1) {
                resolve({
                    result: -1,
                    msg: '该商品不能返利'
                })
                return
            }
            new Promise(resolve => {
                if (link.indexOf('jd') != -1 || item.tpwd) {
                    resolve()
                    return
                }
                getTpwd(item.advLink).then(result => {
                    mongoMng.db.collection('item').update({
                        _id: item._id
                    }, {
                        $set: {
                            tpwd: result
                        }
                    }, (err, result) => {
                        if (err) {
                            log(err);
                            return
                        }
                    })
                    item.tpwd = result
                    resolve()
                }, () => {
                    resolve()
                })
            }).then(() => {
                delete item._id
                delete item.link
                item.rate = Math.round(item.rate * config.returnRate * 100) / 100
                resolve(item)
            })
        })
    })
}

function getFromChrome(link, exclude) {
    exclude = exclude || []
    return new Promise((resolve, reject) => {
        let chromeServer = require('../mng/chromeServerMng').get(exclude)
        if (!chromeServer) {
            require('../mng/pushMng').push('no chrome servers')
            reject()
            return
        }
        var url = chromeServer + 'getAdvLink.do'
        logger.debug('[' + __filename + ':' + __line + ']', 'get from chrome', url, link)
        require('../util/getHtml')({
            url,
            data: JSON.stringify({
                link: link
            })
        }).then(result => {
            logger.debug('[' + __filename + ':' + __line + ']', 'get from chrome', url, link, result)
            var item = JSON.parse(result)
            if (item.result == -1) {
                if (item.msg != '该商品不能返利') {
                    exclude.push(chromeServer)
                    getFromChrome(link, exclude).then(result => {
                        resolve(result)
                    }, result => {
                        reject(result)
                    })

                    if (item.msg.indexOf('登录淘宝联盟超时，等待扫码') != -1) {
                        require('../mng/pushMng').push(item.msg)
                    }

                    return
                }
            }
            new Promise(resolve => {
                if (!item.advLink) {
                    resolve()
                    return
                }
                getTpwd(item.advLink).then(result => {
                    item.tpwd = result
                    resolve()
                }, () => {
                    resolve()
                })
            }).then(() => {
                new Promise((resolve, reject) => {
                    const mongoMng = require('../mng/mongoMng')
                    if (!mongoMng.db) {
                        logger.error('[' + __filename + ':' + __line + '] mongodb未连接')
                        resolve()
                        return
                    }
                    var dbItem = item
                    if (dbItem.advLink) {
                        dbItem.link = link
                        dbItem.createTime = new Date()
                    } else {
                        dbItem = {
                            link: link,
                            advLink: -1,
                            createTime: new Date()
                        }
                    }
                    mongoMng.db.collection('item').find({
                        link: link,
                    }).toArray((err, result) => {
                        if (err) {
                            logger.error('[' + __filename + ':' + __line + ']', err)
                            resolve()
                            return
                        }
                        if (result.length == 0) {
                            //logger.debug('[' + __filename + ':' + __line + '] inert', dbItem)
                            mongoMng.db.collection('item').insert(dbItem, (err, result) => {
                                if (err) {
                                    logger.error('[' + __filename + ':' + __line + ']', err)
                                    resolve()
                                    return
                                }
                                resolve()
                            })
                        } else {
                            //logger.debug('[' + __filename + ':' + __line + '] update', dbItem)
                            mongoMng.db.collection('item').update({
                                _id: result[0]._id
                            }, {
                                $set: dbItem
                            }, (err, result) => {
                                if (err) {
                                    logger.error('[' + __filename + ':' + __line + ']', err)
                                    resolve()
                                    return
                                }
                                resolve()
                            })
                        }
                    })
                }).then(() => {
                    item.link && delete item.link
                    item.createTime && delete item.createTime
                    if (item.rate)
                        item.rate = Math.round(item.rate * config.returnRate * 100) / 100
                    resolve(item)
                })
            })
        }, result => {
            logger.error('[' + __filename + ':' + __line + ']', url, link, result)
            exclude.push(chromeServer)
            getFromChrome(link, exclude).then(result => {
                resolve(result)
            }, result => {
                reject(result)
            })
        })
    })
}

function getTpwd(link) {
    return new Promise((resolve, reject) => {
        require('../mng/taobaoClientMng').client.execute('taobao.tbk.tpwd.create', {
            text: '来自旅悠返利，欢迎再次旅悠返利',
            url: link
        }, function(err, result) {
            if (err) {
                logger.debug('[' + __filename + ':' + __line + ']', err)
                reject()
                return
            }
            resolve(result.data.model)
        })
    })
}

function getActualLink(link) {
    return new Promise((resolve, reject) => {
        new Promise((resolve, reject) => {
            if (link.startsWith('https://detail.tmall.com/item.htm') ||
                link.startsWith('https://detail.m.tmall.com/item.htm') ||
                link.startsWith('https://detail.tmall.hk') ||
                link.startsWith('https://item.taobao.com/item.htm') ||
                link.startsWith('https://login.tmall.com/') ||
                link.startsWith('https://traveldetail.fliggy.com/item.htm') ||
                link.startsWith('https://h5.m.taobao.com/trip/travel-detail/index/index.html') ||
                link.startsWith('https://detail.yao.95095.com/item.htm') ||
                link.startsWith('https://huodong.taobao.com/wow/malldetail/act/guide-tb') ||
                link.startsWith('https://item.jd.com/') ||
                link.startsWith('https://item.m.jd.com/') ||
                link.startsWith('https://shop.m.jd.com/') ||
                link.startsWith('https://i-item.jd.com/') ||
                link.startsWith('https://mitem.jd.hk/')
            ) {
                resolve(link)
                return
            }
            require('../mng/taobaoClientMng').client.execute('taobao.wireless.share.tpwd.query', {
                password_content: link
            }, (err, result) => {
                if (err) {
                    logger.error('[' + __filename + ':' + __line + ']', err)
                    reject()
                    return
                }
                logger.debug('[' + __filename + ':' + __line + ']', 'getActualLink', JSON.stringify(result))
                if (result.url)
                    resolve(result.url)
                else
                    reject()
            })
        }).then(link => {
            var match = /https?:\/\/\S+/.exec(link)
            if (!match) {
                reject('不支持该链接')
                return
            }
            link = match[0]
            new Promise((resolve, reject) => {
                if (link.startsWith('https://detail.tmall.com/item.htm') ||
                    link.startsWith('https://detail.m.tmall.com/item.htm') ||
                    link.startsWith('https://detail.tmall.hk') ||
                    link.startsWith('https://item.taobao.com/item.htm') ||
                    link.startsWith('https://login.tmall.com/') ||
                    link.startsWith('https://traveldetail.fliggy.com/item.htm') ||
                    link.startsWith('https://h5.m.taobao.com/trip/travel-detail/index/index.html') ||
                    link.startsWith('https://detail.yao.95095.com/item.htm') ||
                    link.startsWith('https://huodong.taobao.com/wow/malldetail/act/guide-tb') ||
                    link.startsWith('https://item.jd.com/') ||
                    link.startsWith('https://item.m.jd.com/') ||
                    link.startsWith('https://shop.m.jd.com/') ||
                    link.startsWith('https://i-item.jd.com/') ||
                    link.startsWith('https://mitem.jd.hk/')
                ) {
                    resolve(link)
                    return
                }

                if (link.startsWith('https://market.m.taobao.com/app/nozomi/app-h5-detail/main/index.html')) {
                    let id = require('url').parse(link, true).query.id
                    if (id) {
                        resolve('https://item.taobao.com/item.htm?id=' + id)
                    } else {
                        logger.warn('[' + __filename + ':' + __line + ']', link)
                        reject('该商品不能返利')
                    }
                    return
                }

                // version 1
                // require('../util/getHtml')({
                //     url: link
                // }).then(result => {
                //     if (link.indexOf('http://m.tb.cn/') != -1
                //         || link.indexOf('https://m.tb.cn/') != -1
                //         || link.indexOf('http://www.dwntme.com/') != -1
                //         || link.indexOf('https://www.dwntme.com/') != -1) {
                //         var start = 0, end = 0
                //         while (1) {
                //             start = result.indexOf('<script>', end)
                //             if (start == -1)
                //                 break
                //             end = result.indexOf('</script>', start) + 9
                //             var script = result.substring(start, end),
                //                 s = script.indexOf('url')
                //             if (s != -1) {
                //                 s = script.indexOf('\'', s) + 1
                //                 resolve(script.substring(s, script.indexOf('\'', s)))
                //                 return
                //             }
                //             reject()
                //         }
                //     } else {
                //         var start = 0, end = 0
                //         while (1) {
                //             start = result.indexOf('<script>', end)
                //             if (start == -1)
                //                 break
                //             end = result.indexOf('</script>', start) + 9
                //             var script = result.substring(start, end)
                //             if (script.indexOf('pageData') != -1) {
                //                 try {
                //                     var pageData = JSON.parse(script.substring(script.indexOf('{'), script.lastIndexOf('}') + 1))
                //                     if (pageData && pageData.actionRule && pageData.actionRule[0] && pageData.actionRule[0].url) {
                //                         resolve(pageData.actionRule[0].url)
                //                         return
                //                     }
                //                 } catch (err) {
                //                     log(err)
                //                 }
                //             }
                //         }
                //         reject()
                //     }
                // }, result => {
                //     logger.debug('[' + __filename + ':' + __line + ']', link, result)
                //     reject()
                // })

                // version 2
                // chromeMng.getRedirectLink({
                //     link: link,
                //     test(link) {
                //         return link.startsWith('https://detail.tmall.com/item.htm') ||
                //             link.startsWith('https://detail.m.tmall.com/item.htm') ||
                //             link.startsWith('https://item.taobao.com/item.htm') ||
                //             link.startsWith('https://login.tmall.com/') ||
                //             link.startsWith('https://traveldetail.fliggy.com/item.htm') ||
                //             link.startsWith('https://detail.tmall.hk') ||
                //             link.startsWith('http://chaoshi.detail.tmall.com/item.htm') ||
                //             link.startsWith('https://chaoshi.detail.tmall.com/item.htm')
                //     }
                // })

                // version 3
                getActualLinkFromChrome(link)
                    .then(result => {
                        logger.debug('[' + __filename + ':' + __line + ']', 'redirect link', result)
                        resolve(result)
                    }, result => {
                        if (result)
                            logger.debug('[' + __filename + ':' + __line + ']', result, link)
                        reject(result)
                    })
            }).then(result => {
                if (result.startsWith('https://detail.tmall.com/item.htm') ||
                    result.startsWith('https://detail.m.tmall.com/item.htm') ||
                    result.startsWith('https://item.taobao.com/item.htm') ||
                    result.startsWith('https://traveldetail.fliggy.com/item.htm') ||
                    result.startsWith('https://detail.tmall.hk') ||
                    result.startsWith('http://chaoshi.detail.tmall.com/item.htm') ||
                    result.startsWith('https://chaoshi.detail.tmall.com/item.htm') ||
                    result.startsWith('https://h5.m.taobao.com/trip/travel-detail/index/index.html') ||
                    result.startsWith('https://detail.yao.95095.com/item.htm') ||
                    result.startsWith('https://item.jd.com/') ||
                    result.startsWith('https://item.m.jd.com/') ||
                    result.startsWith('https://shop.m.jd.com/') ||
                    result.startsWith('https://i-item.jd.com/') ||
                    result.startsWith('https://mitem.jd.hk/')
                ) {
                    resolve(result)
                    return
                }
                if (result.startsWith('https://huodong.taobao.com/wow/malldetail/act/guide-tb')) {
                    reuslt = require('url').parse(result, true).query.url
                    if (!result) {
                        logger.debug('[' + __filename + ':' + __line + ']', result)
                        reject('不支持该链接')
                        return
                    }
                    result = decodeURIComponent(result)
                    resolve(result)
                    return
                }
                if (result.startsWith('https://uland.taobao.com/coupon/edetail') ||
                    result.startsWith('https://pages.tmall.com/wow/fsp/act/sample-offering')) {
                    reject('不支持该链接')
                    return
                }
                reuslt = require('url').parse(result, true).query.redirectURL
                if (!result) {
                    logger.debug('[' + __filename + ':' + __line + ']', result)
                    reject('不支持该链接')
                    return
                }
                result = decodeURIComponent(result)
                logger.debug('[' + __filename + ':' + __line + ']', result)
                result = require('url').parse(result, true).query.smReturn
                logger.debug('[' + __filename + ':' + __line + ']', result)
                if (result)
                    resolve(result)
                else
                    reject('不支持该链接')
            }, result => {
                if (result)
                    logger.error('[' + __filename + ':' + __line + ']', result, link)
                reject(result)
            })
        }, result => {
            if (result)
                logger.error('[' + __filename + ':' + __line + ']', result)
            reject(result)
        })
    })
}

function getAdvLink(link, logObj) {
    logger.debug('[' + __filename + ':' + __line + ']', 'getAdvLink', link)
    return new Promise((resolve, reject) => {
        getActualLink(link).then(result => {
            logger.debug('[' + __filename + ':' + __line + ']', 'actual link', result)
            if (logObj && !logObj._id) {
                const mongoMng = require('../mng/mongoMng')
                if (mongoMng.db) {
                    logObj.link = result
                    logObj.time = require('../../lib/formatDate')(new Date())
                    mongoMng.db.collection('log').insert([logObj], (err, result) => {
                        if (err) {
                            logger.error('[' + __filename + ':' + __line + ']', err)
                            return
                        }
                    })
                }
            }
            getFromCouponAPI(result).then(result => {
                logger.debug('[' + __filename + ':' + __line + '] has coupon', JSON.stringify(result))
                resolve(result)
            }, () => {
                logger.debug('[' + __filename + ':' + __line + '] no coupon', result)
                getFromJDAPI(result).then(result => {
                    logger.debug('[' + __filename + ':' + __line + '] get from jd api', JSON.stringify(result))
                    resolve(result)
                }, () => {
                    logger.debug('[' + __filename + ':' + __line + '] fail from jd api', JSON.stringify(result))
                    getFromDB(result).then(result => {
                        logger.debug('[' + __filename + ':' + __line + '] is in db', JSON.stringify(result))
                        resolve(result)
                    }, () => {
                        logger.debug('[' + __filename + ':' + __line + '] not in db', result)
                        getFromChrome(result).then(result => {
                            logger.debug('[' + __filename + ':' + __line + '] get from chrome', JSON.stringify(result))
                            resolve(result)
                        }, () => {
                            logger.debug('[' + __filename + ':' + __line + '] fail from chrome', result)
                            reject()
                        })
                    })
                })
            })
        }, result => {
            logger.error('[' + __filename + ':' + __line + ']', result || '', link)
            if (result == '不支持该链接') {
                resolve({
                    result: -1,
                    msg: result
                })
            } else {
                reject(result)
                if (result)
                    require('../mng/pushMng').push(result)
            }
        })
    })
}

exports.getActualLink = getActualLink
exports.getAdvLink = getAdvLink